package com.atguigu.gmall.order.controller;

import com.atguigu.gmall.cart.client.CartInfoFeignClient;
import com.atguigu.gmall.common.result.Result;
import com.atguigu.gmall.common.util.AuthContextHolder;
import com.atguigu.gmall.model.cart.CartInfo;
import com.atguigu.gmall.model.order.OrderDetail;
import com.atguigu.gmall.model.order.OrderInfo;
import com.atguigu.gmall.model.user.UserAddress;
import com.atguigu.gmall.order.service.OrderInfoService;
import com.atguigu.gmall.user.UserInfoFeignClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.HttpRequestHandler;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors;

/**
 * @author: 李旭
 * @create: 2021-09-10 11:40
 **/
@RestController
@RequestMapping("/api/order")
public class OrderApiController {

    @Autowired
    private CartInfoFeignClient cartInfoFeignClient;
    @Autowired
    private UserInfoFeignClient userInfoFeignClient;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private OrderInfoService orderInfoService;

    //去结算页面所需要的数据
    @GetMapping("/getTradeData")
    public Map getTradeData(HttpServletRequest request){

        Map result = new HashMap();
        //1、收货地址
        List<UserAddress> userAddressList = userInfoFeignClient.findUserAddressList();
        result.put("userAddressList",userAddressList);
        //2、商品清单
        List<CartInfo> cartInfoListByIsChecked = cartInfoFeignClient.findCartInfoListByIsChecked();
        //2.1: 真正的商品清单
        List<OrderDetail> detailArrayList = cartInfoListByIsChecked.stream().map(cartInfo -> {
            OrderDetail orderDetail = new OrderDetail();
            orderDetail.setSkuId(cartInfo.getSkuId());
            orderDetail.setSkuNum(cartInfo.getSkuNum());
            orderDetail.setSkuName(cartInfo.getSkuName());
            orderDetail.setImgUrl(cartInfo.getImgUrl());
            orderDetail.setOrderPrice(cartInfo.getSkuPrice());//小心： 设置实时价格
            return orderDetail;
        }).collect(Collectors.toList());
        result.put("detailArrayList",detailArrayList);

        //3、总计  Stream 尽量使用Stream 官方 Stream性能是高  可读性是极差
        //3.1: 总件数  summarizing:汇总   3  4  1  7   求和  求AVG 求最大 求最小
        long totalNum = detailArrayList.stream().collect(
                Collectors.summarizingInt(OrderDetail::getSkuNum)).getSum();
        result.put("totalNum",totalNum);
        //3.2: 总金额   钱方面
     /*   double totalAmount = detailArrayList.stream().collect(
                Collectors.summarizingDouble(orderDetail -> {
                    return orderDetail.getOrderPrice().doubleValue()*orderDetail.getSkuNum();
                })).getSum();*/
         //几个月之后 发现钱少了   == 456.7892   财务：钱对不上帐
        BigDecimal bigDecimal = new BigDecimal(0);
        for (OrderDetail orderDetail : detailArrayList) {
            bigDecimal = bigDecimal.add(orderDetail.getOrderPrice().
                    multiply(new BigDecimal(orderDetail.getSkuNum())));
        }
        result.put("totalAmount",bigDecimal);
        //4、订单号
        //4.1:  MD5(userId+盐值) == 交易号
        //4.2:  UUID == 交易号  将UUID保存Redis缓存中 删除掉
        //4.3: 分布式锁  setnx   setnx(k,v)  如果K存在了 返回值是0 已经提交过了
        //                         只有第一次提交  如果K不存在 返回值是1  未提交过
        String uuid = UUID.randomUUID().toString();
        String userId = AuthContextHolder.getUserId(request);
        redisTemplate.opsForValue().set("tradeNo:" + userId,uuid);
        result.put("tradeNo",uuid);
        return result;
    }
    //提交订单   VUE AJax 异步请求 要求必须登录   网关 ：auth必须登录
    @PostMapping("/auth/submitOrder")
    public Result submitOrder(@RequestBody OrderInfo orderInfo,String tradeNo
       ,HttpServletRequest request){
        String userId = AuthContextHolder.getUserId(request);
        //1、校验交易号  防止幂等性问题
        Object no = redisTemplate.opsForValue().get("tradeNo:" + userId);
        if(null != no && no.equals(tradeNo)){
            //交易号正确
            redisTemplate.delete("tradeNo:" + userId);
            //2、校验是否库存  如果没有库存了 进行友情提示(库存不足）  如果有库存 再继续
            List<OrderDetail> orderDetailList = orderInfo.getOrderDetailList();
            for (OrderDetail orderDetail : orderDetailList) {
                //连接仓库系统  问一问 是否有库存
                boolean flag = orderInfoService.hasStock(orderDetail);
                if(!flag){
                    //无货
                    return Result.fail().message(orderDetail.getSkuName() + "[库存不足]");
                }
            }
            //保存
            orderInfo.setUserId(Long.parseLong(userId));
            Long orderId = orderInfoService.saveOrder(orderInfo);

            return Result.ok(orderId);
        }
        return Result.fail().message("不要重复提交订单");
    }
    //根据订单的ID　查询订单对象
    @GetMapping("/getOrderInfo/{orderId}")
    public OrderInfo getOrderInfo(@PathVariable Long orderId){

        return orderInfoService.getOrderInfo(orderId);
    }

    //拆单  // http://order.gmall.com/api/order/orderSplit?orderId=xxx&wareSkuMap=xxx
    @PostMapping("/orderSplit")
    public List<Map> orderSplit(Long orderId,String wareSkuMap){
        //开始拆单  [{"wareId":"1","skuIds":["2","10"]},{"wareId":"2","skuIds":["3"]}]
        List<OrderInfo> orderInfoList = orderInfoService.orderSplit(orderId,wareSkuMap);
        //List<Map>
        return orderInfoList.stream().map(orderInfo ->
                orderInfoService.initWareOrder(orderInfo)).collect(Collectors.toList());

    }
}
